﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using Might.Infrastructure.Annotations.Graphics;

namespace Might.GraphicsEditor.GraphicsObjects {

    /// <summary>
    /// Top class in editable objects hierarchy
    /// </summary>
    public class GraphicsComponent : UserControl {
        internal IGraphicsItem ga { get; set; }

        internal bool IsMouseCaptured { get; set; }

        /// <summary>
        /// Coordinate for distance from left border of the Canvas
        /// </summary>
        public virtual double Left {
            get { return Canvas.GetLeft(this); }
            set { Canvas.SetLeft(this, value); }
        }

        /// <summary>
        /// Coordinate for distance from top border of the Canvas
        /// </summary>
        public virtual double Top {
            get { return Canvas.GetTop(this); }
            set { Canvas.SetTop(this, value); }
        }

        protected virtual void GaGraphicsPrimitiveChanged(object sender, EventArgs e) {
            UpdateShape();
            /*if (DrawCanvas.SelectedCanvas != null) {
                DrawCanvas.SelectedCanvas.resizer.UpdateRect();
            }*/
        }

        protected virtual void UpdateShape() {
            RenderTransform = null;
            if (Width != ga.Width) {
                Width = ga.Width;
            }
            if (Height != ga.Height) {
                Height = ga.Height;
            }
            if (Top != ga.Top) {
                Top = ga.Top;
            }
            if (Left != ga.Left) {
                Left = ga.Left;
            }
        }
    }

    /// <summary>
    /// Basic class for representing simple graphics objects, based on Windows.Shape
    /// </summary>
    public abstract class GraphicsLeaf : GraphicsComponent {
        internal Path Path { get; set; }

        /// <summary>
        /// Color of the stroke
        /// </summary>
        public Brush Stroke {
            get { return Path.Stroke; }
            set { Path.Stroke = value; }
        }

        /// <summary>
        /// Color of the filled area
        /// </summary>
        public Brush Fill {
            get { return Path.Fill; }
            set { Path.Fill = value; }
        }

        /// <summary>
        /// Thickness of the outline
        /// </summary>
        public double StrokeThickness {
            get { return Path.StrokeThickness; }
            set { Path.StrokeThickness = value; }
        }

        protected override void UpdateShape() {
            base.UpdateShape();
            IGraphicsFilledShape g = ga as IGraphicsFilledShape;
            if (g == null) {
                throw new NullReferenceException("Updating Null anotation");
            }
            if (Fill != g.Fill) {
                Fill = g.Fill;
            }
            if (Stroke != g.Stroke) {
                Stroke = g.Stroke;
            }
            if (StrokeThickness != g.Thickness) {
                StrokeThickness = g.Thickness;
            }
        }
    }

    // TODO complete Modelica brushes static class
    /// <summary>
    /// Static Modleica Brushes
    /// </summary>
    public static class MBrushes {
        /*	<LinearGradientBrush SpreadMethod="Repeat" EndPoint="0.5,1" StartPoint="0.5,0.96">
					<GradientStop Color="#FF000000" Offset="0.25"/>
					<GradientStop Color="#FFFFFFFF" Offset="0.25"/>
				</LinearGradientBrush>*/

        //Cross,  CrossDiag
        private static readonly LinearGradientBrush horizontal;
        private static readonly LinearGradientBrush vertical;
        private static readonly LinearGradientBrush forward;
        private static readonly LinearGradientBrush backward;

        static MBrushes() {
            var gs = new GradientStopCollection {
                new GradientStop {
                    Color = Colors.Black,
                    Offset = 0.25
                }, new GradientStop {
                    Color = Colors.White,
                    Offset = 0.25
                }
            };

            horizontal = new LinearGradientBrush(gs, 0) {
                SpreadMethod = GradientSpreadMethod.Repeat,
                StartPoint = new Point(0.5, 1),
                EndPoint = new Point(0.5, 0.95)
            };
            vertical = new LinearGradientBrush(gs, 90) {
                SpreadMethod = GradientSpreadMethod.Repeat,
                StartPoint = new Point(0.5, 1),
                EndPoint = new Point(0.5, 0.95)
            };
            forward = new LinearGradientBrush(gs, 45) {
                SpreadMethod = GradientSpreadMethod.Repeat,
                StartPoint = new Point(0.5, 1),
                EndPoint = new Point(0.5, 0.95)
            };
            backward = new LinearGradientBrush(gs, 135) {
                SpreadMethod = GradientSpreadMethod.Repeat,
                StartPoint = new Point(0.5, 1),
                EndPoint = new Point(0.5, 0.95)
            };
        }

        private static LinearGradientBrush Horizontal {
            get { return horizontal; }
        }

        private static LinearGradientBrush Vertical {
            get { return vertical; }
        }

        private static LinearGradientBrush Forward {
            get { return forward; }
        }

        private static LinearGradientBrush Backward {
            get { return backward; }
        }
    }
}
